package com.wxy;


import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.http.HttpHost;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.client.indices.GetIndexResponse;
import org.elasticsearch.cluster.metadata.MappingMetadata;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms.Bucket;
import org.elasticsearch.search.aggregations.metrics.Stats;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.xcontent.XContentType;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@SpringBootTest
@Data
@AllArgsConstructor
@NoArgsConstructor
class user{
	int age;
	String city;
	String email;
	String name;
}
public class JunitTest2 {
	private RestHighLevelClient client;
	private static final String MAPPING_JSON ="{\n" +
	        "  \"mappings\": {\n" +
	        "    \"properties\": {\n" +
	        "      \"name\": {\n" +
	        "        \"type\": \"text\",\n" +
	        "        \"analyzer\": \"standard\"\n" +
	        "      },\n" +
	        "      \"age\": {\n" +
	        "        \"type\": \"integer\"\n" +
	        "      },\n" +
	        "      \"email\": {\n" +
	        "        \"type\": \"keyword\",\n" +
	        "        \"index\": false\n" +
	        "      }\n" +
	        "    }\n" +
	        "  }\n" +
	        "}";
	@BeforeEach		//test测试之前初始化client
	void setup() {
		client=new RestHighLevelClient(RestClient.builder(HttpHost.create("http://localhost:9200")));
	}
	@AfterEach		//test测试之后要关闭client连接
	void close() throws IOException {
		client.close();
	}
	
	//操作mapping
	//@Test		//查询mapping映射成功
	public void get() throws IOException {
		GetIndexRequest request=new GetIndexRequest("user");
		//通过查询mapping是否存在
//		Boolean isBoolean=client.indices().exists(request, RequestOptions.DEFAULT);
//		System.out.println(isBoolean);
		//查询mapping具体内容
		GetIndexResponse getIndexResponse=client.indices().get(request,RequestOptions.DEFAULT);
		Map<String, MappingMetadata> map=getIndexResponse.getMappings();
		Set<String> set=map.keySet();
		for (String string : set) {
			MappingMetadata mappingMetadata=map.get(string);
			Map<String, Object> sourceAsMap = mappingMetadata.getSourceAsMap();
            System.out.println("Index: " + string);
            System.out.println("Mapping: " + sourceAsMap);
		}
	}
	//@Test		//删除mapping映射成功
	public void delete() throws IOException {
		DeleteIndexRequest request=new DeleteIndexRequest("user");
		client.indices().delete(request,RequestOptions.DEFAULT);
	}
	//@Test		//创建mapping映射失败★★★
	public void create() throws IOException {
	    CreateIndexRequest createIndexRequest = new CreateIndexRequest("user");
	    createIndexRequest.source(MAPPING_JSON, XContentType.JSON);
	    client.indices().create(createIndexRequest, RequestOptions.DEFAULT);
	}
	
	//操作文档
	//@Test		//添加文档成功
	public void createdoc() throws IOException {
		//准备request		查询id是否存在，存在修改，不存在添加
		IndexRequest indexRequest=new IndexRequest("user").id("1");
		//准备请求参数
		user user1=new user(19,"北京","1639637964@qq.com","申公豹");
		indexRequest.source(JSONUtil.toJsonStr(user1),XContentType.JSON);
		//发送请求
		client.index(indexRequest,RequestOptions.DEFAULT);
	}
	//@Test		//查询文档
	public void getdoc() throws IOException {
		GetRequest getRequest=new GetRequest("user","1");
//		Boolean boolean1=client.exists(getRequest,RequestOptions.DEFAULT);
//		System.out.println(boolean1);
		GetResponse getResponse=client.get(getRequest,RequestOptions.DEFAULT);
		//将文档封装为bean
		Map<String,Object> map=getResponse.getSource();
		user newuser=BeanUtil.toBean(map,user.class);
		System.out.println(newuser.toString());
		//输出文档内容
		Set<String> key=map.keySet();
		for (String string : key) {
			Object value=map.get(string);
			System.out.println(string+"->"+value);
		}
	}
	//@Test		//修改文档
	public void updatedoc() throws IOException {
		UpdateRequest request=new UpdateRequest("user","1");
		request.doc(
				"age",22,
				"city","上海"
				);
		client.update(request,RequestOptions.DEFAULT);
	}
	//@Test		//删除文档
	public void deletedoc() throws IOException {
		DeleteRequest deleteRequest=new DeleteRequest("user").id("1");
		DeleteResponse deleteResponse=client.delete(deleteRequest,RequestOptions.DEFAULT);
		System.out.println(deleteResponse.status()+"..."+deleteResponse.toString());
	}
	
	//批量操作文档
	//@Test
	public void bulkdoc() throws IOException {
		BulkRequest request=new BulkRequest();
		user addUser=new user(19,"安徽","78725762@qq.com","哪吒");
		String jsonString=JSONUtil.toJsonStr(addUser);
		request.add(new IndexRequest("user").id("2").source(jsonString,XContentType.JSON));
		request.add(new IndexRequest("user").id("3").source(jsonString,XContentType.JSON));
		//request.add(new DeleteIndexRequest())批量删除
		client.bulk(request,RequestOptions.DEFAULT);
	}
	//dsl查询
	//@Test
	public void getByDsl() throws IOException {
		//初始化request
		SearchRequest request=new SearchRequest("user");
		//查询全部
		request.source().query(QueryBuilders.matchAllQuery());
//		//分页查询
//		request.source().from(0);
//		request.source().size(1);
//		//排序
//		request.source().sort("age",SortOrder.DESC);
//		//条件查询
//		request.source().query(QueryBuilders.matchQuery("name","哪吒"));
//		//精确查询
//		request.source().query(QueryBuilders.termQuery("age",19));
//		//范围查询
//		request.source().query(QueryBuilders.rangeQuery("age").lt(20).gt(10));
//		//bool查询
//		request.source().query(QueryBuilders.boolQuery()
//				.must(QueryBuilders.matchQuery("name","哪吒"))
//				.should(QueryBuilders.termQuery("age",18))
//				.should(QueryBuilders.termQuery("age",22))
//				.mustNot(QueryBuilders.termQuery("age",19))
//				);
		//高亮查询
		request.source().query(QueryBuilders.matchQuery("name","哪吒"));
		request.source().highlighter(SearchSourceBuilder.highlight()
				.field("name").preTags("<em>").postTags("</em>"));
		//发送请求
		SearchResponse response=client.search(request,RequestOptions.DEFAULT);
		SearchHits hits=response.getHits();
		long value=hits.getTotalHits().value;
		System.out.println(value);
		SearchHit[] hits2=hits.getHits();
		for (SearchHit searchHit : hits2) {
			String string=searchHit.getSourceAsString();
			System.out.println(string);
			//高亮查询添加
			Map<String, HighlightField> maps=searchHit.getHighlightFields();
			if(CollUtil.isNotEmpty(maps)) {
				HighlightField highlightField=maps.get("name");
				if(highlightField!=null)
					System.out.println(highlightField.getFragments()[0].toString());
				}
		}
	}
	//聚合函数
	@Test
	public void juhe() throws IOException {
		SearchRequest request=new SearchRequest("user");
		//组合查询
		request.source().query(QueryBuilders.boolQuery().must(QueryBuilders.termQuery("age",19)));
		//不查询文档
		request.source().size(0);
		//设置聚合查询条件
		request.source().aggregation(AggregationBuilders.terms("city_terms").field("city")
									.subAggregation(AggregationBuilders.stats("age_stats").field("age")));
		//发送请求
		SearchResponse response=client.search(request,RequestOptions.DEFAULT);
		//处理结果
		Aggregations aggregations=response.getAggregations();
		Terms terms=aggregations.get("city_terms");
		List<? extends Bucket> listsBuckets=terms.getBuckets();
		for (Bucket bucket : listsBuckets) {
			String keyString=bucket.getKeyAsString();
			long nums=bucket.getDocCount();
			System.out.println("key："+keyString+"\n"+"doc_count："+nums);
			Stats ageStats = bucket.getAggregations().get("age_stats");
            if (ageStats != null) {
                System.out.println("年龄统计信息:");
                System.out.println("  数量: " + ageStats.getCount());
                System.out.println("  最小值: " + ageStats.getMin());
                System.out.println("  最大值: " + ageStats.getMax());
                System.out.println("  平均值: " + ageStats.getAvg());
                System.out.println("  总和: " + ageStats.getSum());
            }
            else {
				System.out.println(ageStats+"为空");
			}
		}
    }
}